#!/usr/bin/python2

# cronjobs are run on releng01.stg
# Looks like:
# /usr/local/bin/owner-sync-pkgdb f19 
# /usr/local/bin/owner-sync-pkgdb dist-5E-epel 
# /usr/local/bin/owner-sync-pkgdb dist-6E-epel
# /usr/local/bin/owner-sync-pkgdb epel7 

import sys
import os
import ConfigParser
from urlparse import urljoin

import requests

DEBUG=False
VERIFY=True
{% if env == 'staging' %}
BASEURL = os.environ.get('PACKAGEDBURL') or 'https://admin.stg.fedoraproject.org/pkgdb/'
{% else %}
BASEURL = os.environ.get('PACKAGEDBURL') or 'https://admin.fedoraproject.org/pkgdb/'
{% endif %}
if not BASEURL.endswith('/'):
    BASEURL = BASEURL + '/'

# Why do we have this?  Seems insecure....
sys.path.append('.')

import koji

rawhide = '27'
extraArchList = {'kernel': ('i586', 'i686', 'noarch'),
                 'kernel-xen-2.6': ('i586', 'i686', 'noarch'),
                 'glibc': ('i686',),
                 'openssl': ('i686',),
                 'em8300-kmod': ('i586', 'i686'),
                 'sysprof-kmod': ('i586', 'i686'),
                }

def usage():
    print "Usage: owner-sync <tag>"
    print "    <tag>: tag to synchronize owners for"
    sys.exit(1)

def get_options():
    # shamelessly stolen from koji CLI
    opts = {
{% if env == 'staging' %}
        'server': 'https://koji.stg.fedoraproject.org/kojihub',
        'weburl': 'https://koji.stg.fedoraproject.org/koji',
{% else %}
        'server': 'https://koji.fedoraproject.org/kojihub',
        'weburl': 'https://koji.fedoraproject.org/koji',
{% endif %}
        'principal': 'pkgdb/{{inventory_hostname}}@{{ipa_realm}}',
        'keytab': '/etc/krb5.pkgdb_{{inventory_hostname}}.keytab',
    }
    for configFile in ('/etc/koji.conf', os.path.expanduser('~/.koji/config')):
        if os.access(configFile, os.F_OK):
            f = open(configFile)
            config = ConfigParser.ConfigParser()
            config.readfp(f)
            f.close()
            if config.has_section('koji'):
                for name, value in config.items('koji'):
                    if opts.has_key(name):
                        opts[name] = value
    for entry in opts.keys():
        if entry == 'server' or entry == 'weburl':
            pass
    return opts

if __name__ == '__main__':
    try:
        tag=sys.argv[1]
    except:
        print "ERROR: no tag specified!\n"
        usage()

    if 'container' in tag:
        namespace='container'
        version = tag.split('-')[0].split('f')[1]
    elif tag == 'module-package-list':
        # See https://pagure.io/releng/issue/6663
        # and https://pagure.io/fm-orchestrator/issue/333
        namespace = 'rpms'
        version = rawhide
    else:
        namespace='rpms'
        if tag.startswith('epel'):
            version = tag.split('epel')[1]
        elif tag.startswith('f'):
            version = tag.split('f')[1]
        else:
            version = tag.split('-')[1][:-1]

    if tag.startswith('epel'):
        # Ex: epel7 => epel7
        reponame = tag
        arches = ["primary"]
    elif tag.endswith('epel'):
        # Ex: dist-6E-epel => el6
        reponame = 'el%s' % version
        arches = ["primary"]
    elif tag == 'module-package-list':
        reponame = 'master'
        arches = ["primary"]
    else:
        # Fedora 
        if version == rawhide:
            reponame = 'master'
        else:
            reponame = tag.split('-')[0]
{% if env == 'staging' %}
        arches = ["primary"]
{% else %}
        if version <= "25":
            arches = ["primary", "arm", "ppc", "s390"]
        else:
            arches = ["primary", "s390"]
{% endif %}

    data = requests.get(urljoin(BASEURL, 'api/collections'), verify=VERIFY).json()
    branch_names = set()
    for collection in (c for c in data['collections'] if c['status'] != 'EOL'):
        ### TODO: check with pingou that this is now returning the same
        # format as the collection names in api/vcs
        # By moving the data from gitbranchname into branchname, I think
        # that the data will now match
        branch_names.add(collection['branchname'])

    if reponame not in branch_names:
        print 'tag %s => repo %s: does not seem to be a non-EOL branch' % (tag, reponame)
        sys.exit(1)

    data = requests.get(urljoin(BASEURL, 'api/vcs?format=json'), verify=VERIFY).json()
    acls = data[namespace]
    pkgs = {}
    for pkg_name in acls:
        try:
            owners = acls[pkg_name][reponame]
        except KeyError:
            # Package is not branched for this release
            continue
        if len(owners['commit']['people']):
            # Arbitrarily take the first committer listed as the owner in
            # koji
            pkgs[pkg_name] = owners['commit']['people'][0]
        else:
            pkgs[pkg_name] = 'orphan'

    if tag == 'module-package-list' and not 'module-build-macros' in pkgs:
        pkgs['module-build-macros'] = 'releng'

    pkgList = pkgs.keys()
    pkgList.sort()

    options = get_options()

    for arch in arches:
        if arch == "primary":
            session = koji.ClientSession("https://koji{{env_suffix}}.fedoraproject.org/kojihub", {'krb_rdns': False})
        else:
            session = koji.ClientSession("https://%s.koji.fedoraproject.org/kojihub" % arch, {'krb_rdns': False})
        try:
            session.krb_login(options['principal'], options['keytab'])
        except:
            print "Unable to sync to %s hub" % arch
            continue
        kojitag = session.getTag(tag)
        if kojitag is None:
            print "ERROR: tag %s does not exist for arch %s!\n" % (tag, arch)
            usage()

        kojipkgs = {}
        kojiusers = [user['name'] for user in session.listUsers()]

        for p in session.listPackages(tagID=tag, inherited = True):
            kojipkgs[p['package_name']] = p

        for pkg in pkgList:
            owner = pkgs[pkg]
            if DEBUG:
                print '[DEBUG] Package: %s, Owner: %s' % (pkg, owner)

            if not owner in kojiusers:
                # add the user first
                if DEBUG:
                    print "Adding user %s" % owner
                else:
                    try:
                        session.createUser(owner)
                    except:
                        # user already exists
                        continue
                    kojiusers.append(owner)

            if not kojipkgs.has_key(pkg):
                if DEBUG:
                    print "Adding package %s for %s with owner %s" % (pkg, tag, owner)
                else:
                    extraArches = None
                    if pkg in extraArchList:
                        extraArches = extraArchList[pkg]
                    session.packageListAdd(tag, pkg, owner = owner, extra_arches=extraArches)
            elif kojipkgs[pkg]['owner_name'] != owner:
                if DEBUG:
                    print "Setting owner for %s in %s to %s" % (pkg, tag, owner)
                else:
                    session.packageListSetOwner(tag, pkg, owner, force = True)
